package com.seres.backend.admin;

import java.util.ArrayList;
import java.util.List;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;

public class MessagesParser {
	private static final int MESSAGE_ID_COL_NR = 1;
	private static final int MESSAGE_COL_NR = 2;
	private static final int RISK_IMPACT_COL_NR = 3;
	private static final int IMPACT_SCORE_COL_NR = 5;
	private static final int STAKEHOLDER_COL_NR = 5;
	
	private static final int TITLE_COL_NR = 1;
	private static final int TITLE_ROW_NR = 1;
	private static final String TITLE = "messages";
	
	private XSSFSheet worksheet;
	private List<Integer> allowedStakeholderIds;
	private boolean dataEndReached = false;
	private static final int DATA_START_ROW_NR = 3;
	
	public MessagesParser(XSSFSheet worksheet, List<Integer> allowedStakeholderIds){
		setWorksheet(worksheet);
		setAllowedStakeholderIds(allowedStakeholderIds);
	}
	public MessagesParserResult parse(){
		MessagesParserResult messagesParserResult = new MessagesParserResult();
		List<Integer> stakeholderIds = parseStakeholderIds();
		messagesParserResult.setStakeholderIds(stakeholderIds);
		
		for(int i = 0; !isDataEndReached(); i++){
			XSSFRow row = getWorksheet().getRow(DATA_START_ROW_NR + i);

			if(containsData(row.getCell(MESSAGE_ID_COL_NR))){
				int messageId = parseMessageId(row.getCell(MESSAGE_ID_COL_NR));
				String message = parseMessage(row.getCell(MESSAGE_COL_NR));
				int riskImpact = parseRiskImpact(row.getCell(RISK_IMPACT_COL_NR));
				
				System.out.println("messageId: " + messageId);
				System.out.println("message: " + message);
				System.out.println("riskImpact: " + riskImpact);
				
				List<Integer> impactScores = new ArrayList<Integer>();
				for(int j = 0; j < stakeholderIds.size(); j++){
					int impactScore = parseImpactScore(row.getCell(IMPACT_SCORE_COL_NR + j));
					System.out.println("impactScore: " + impactScore);
					impactScores.add(impactScore);
				}
				messagesParserResult.addMessageLine(new MessageLine(messageId, message, riskImpact, impactScores));
			}
			else{
				setDataEndReached(true);
			}
		}
		return messagesParserResult;
	}
	private int parseImpactScore(XSSFCell cell) {
		if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
			return (int) cell.getNumericCellValue();
		}
		else{
			throw new IllegalArgumentException("invalid impact score cell");
		}
	}
	private int parseRiskImpact(XSSFCell cell) {
		if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
			return (int) cell.getNumericCellValue();
		}
		else{
			throw new IllegalArgumentException("invalid risk impact cell");
		}
	}
	private String parseMessage(XSSFCell cell) {
		if(cell.getCellType() == Cell.CELL_TYPE_STRING){
			return cell.getStringCellValue();
		}
		else{
			throw new IllegalArgumentException("invalid message cell");
		}
	}
	private int parseMessageId(XSSFCell cell) {
		if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
			return (int) cell.getNumericCellValue();
		}
		else{
			throw new IllegalArgumentException("invalid message id cell");
		}
	}
	private List<Integer> parseStakeholderIds() {
		XSSFRow row = getWorksheet().getRow(DATA_START_ROW_NR-1);
		boolean endReached = false;
		List<Integer> stakeholderIds = new ArrayList<Integer>();
		
		
		for(int i = 0; !endReached; i++){
			if(containsData(row.getCell(STAKEHOLDER_COL_NR + i))){
				stakeholderIds.add(parseStakeholderId(row.getCell(STAKEHOLDER_COL_NR + i)));				
			}
			else{
				endReached = true;
			}

		}
		return stakeholderIds;
	}
	private int parseStakeholderId(XSSFCell cell) {
		if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC && canHaveAsStakeholderId((int) cell.getNumericCellValue())){
			return (int) cell.getNumericCellValue();
		}
		else{
			throw new IllegalArgumentException("invalid message id cell");
		}
	}
	private boolean canHaveAsStakeholderId(int numericCellValue) {
		return getAllowedStakeholderIds().contains(numericCellValue);
	}
	private boolean containsData(XSSFCell cell){
		return cell.getCellType() != Cell.CELL_TYPE_BLANK;
	}
	private void setWorksheet(XSSFSheet worksheet) {
		if(canHaveAsWorksheet(worksheet)){
			this.worksheet = worksheet;
		}
		else{
			throw new IllegalArgumentException("invalid modules worksheet");
		}
		
	}
	public boolean canHaveAsWorksheet(XSSFSheet worksheet){
		return worksheet.getRow(TITLE_ROW_NR).getCell(TITLE_COL_NR).getStringCellValue().toLowerCase().equals(TITLE);
	}
	private boolean isDataEndReached() {
		return dataEndReached;
	}
	private void setDataEndReached(boolean dataEndReached) {
		this.dataEndReached = dataEndReached;
	}
	private XSSFSheet getWorksheet() {
		return worksheet;
	}
	private void setAllowedStakeholderIds(List<Integer> allowedStakeholderIds) {
		this.allowedStakeholderIds = allowedStakeholderIds;
	}
	public List<Integer> getAllowedStakeholderIds() {
		return allowedStakeholderIds;
	}
}
